#include "smilecatch.h"
#include "ui_smilecatch.h"
#include <chrono>
#include <iomanip>
#include <sstream>

using namespace std;
using namespace cv;

CascadeClassifier scascade;


SmileCatch::SmileCatch(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SmileCatch)
{
    ui->setupUi(this);

    connect(ui->back,&QPushButton::clicked,[=](){
        emit this->back();
    });
}

SmileCatch::~SmileCatch()
{
    delete ui;
}

string getTimeStamp() {
    // 获取当前时间
    auto now = chrono::system_clock::now();
    time_t timeStamp = chrono::system_clock::to_time_t(now);

    // 转换为本地时间
    tm localTime;
    localtime_s(&localTime, &timeStamp);

    // 格式化时间字符串
    stringstream sstream;
    sstream << put_time(&localTime, "%Y-%m-%d_%H-%M-%S"); // 在这里设置时间格式
    string timeStampStr = sstream.str();

    return timeStampStr;
}

void SmileCatch::on_start_clicked()
{
    stop = false;
    ui->info->clear();
    bool sig = 0;
    chrono::steady_clock::time_point startTime;

    //调用摄像头
    VideoCapture video;
    video.open(0);

    //检测摄像头是否成功打开
    if (!video.isOpened()) {
        qDebug() << "摄像头加载出错！";
        exit(-1);
    }

    /*已训练的人脸识别算法，具体路径需要根据opencv库安装位置在config.h更改*/
    const string casPath = HAAR_PATH;
    const string scasPath = SMILE_PATH;

    //检测是否成功加载级联分类器
    if (!scascade.load(casPath)) {
        qDebug() << "算法加载失败！";
        exit(-1);
    }

    string lastFilePath = ""; // 定义一个空字符串，表示最后一个文件路径为空

    while (stop != true) {
        Mat vClip;
        video >> vClip;  //视频转为图像

        //若突然没有视频信号则结束
        if (vClip.empty()) {
            break;
        }

        //灰度化，减少计算
        Mat imgGray;
        cvtColor(vClip, imgGray, COLOR_BGR2GRAY);
        vector<Rect> smiles(0);
        scascade.detectMultiScale(imgGray, smiles, 1.1, 50, CASCADE_SCALE_IMAGE,Size(30,30));//调用微笑识别算法
        if (smiles.size() > 0) {
            for (size_t i = 0; i < smiles.size(); i++) {
                rectangle(vClip, smiles[i], Scalar(0, 0, 255), 2, 8, 0);  //生成矩形框出人脸
            }
        }


        if (smiles.size() > 0 && !sig) {
            ui->info->setText("请保持微笑，即将抓拍😀");
            sig = 1;
            startTime = chrono::steady_clock::now();
        }

        else if (sig) {
            chrono::steady_clock::time_point currentTime = chrono::steady_clock::now();
            chrono::duration<double> interval = currentTime - startTime;

            if (interval.count() > 2.0) {
                //停止读取视频信号
                stop = true;
                //生成图片文件名，并将图像保存到本地
                // 生成保存图像的文件名（使用时间戳作为图像名）
                  string timeStampStr = getTimeStamp();
                  string filePath = timeStampStr + ".jpg";
                try {
                    imwrite(filePath,vClip);
                    qDebug()<<"Saved smile image to " << QString::fromStdString(filePath);
                } catch (Exception& e) {
                       cout<<"Exception caught:"<<e.msg<<endl;
                }
                  lastFilePath = filePath; // 更新最后一个文件路径

            }
        }

    // 在界面上显示当前帧的原始图像
    QImage qImg((const unsigned char*)(vClip.data), vClip.cols, vClip.rows, QImage::Format_RGB888);
    qImg = qImg.rgbSwapped().scaled(ui->origin->size(), Qt::KeepAspectRatio);
    ui->origin->setPixmap(QPixmap::fromImage(qImg));

    waitKey(1);
    QApplication::processEvents();
    }
       // 停止视频捕获并释放所有资源
       video.release();

       // 如果成功截取到微笑图片，则在界面上显示该图片
       if (!lastFilePath.empty()) {
           // 加载微笑图片并将其显示到界面上
           QPixmap qPixmap(QString::fromStdString(lastFilePath));
           ui->origin->setPixmap(qPixmap.scaled(ui->origin->size(), Qt::KeepAspectRatio));
       }
}


void SmileCatch::on_back_clicked()
{
    stop = true;
    ui->origin->clear();
    ui->info->clear();
}
